/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//    Copyright(c) 2001 Intel Corporation. All Rights Reserved.
//
//  VSS: 
//     $Workfile: $
//     $Revision: $
//     $Date:     $
//     $Archive:  $
//
//  Description:
//
//  History:
//     Date        Author        Changes
//     2001/8/7   Jerry Hu       Created  (Version 0.1)
//
********************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <memory.h>

#include "ijx.h"

#include "dib.h"
#include "jpgcmd.h"

#include <sys/time.h>


#define _GET_TIME_ON__ 1

extern struct timeval tv3;
extern struct timezone tz;

///////////////////////////////////////////////////////////////////////////////
//  JPEGtoBMP
int JPEGtoBMP ( int      nDesiredColor,
                MDIBSPEC *pDIBSpec,
                FILE     *file)
{
    int              nBufLen;
    Ipp8u            *pBuf;
    int              nImageStep;
    Ipp8u            *pImageBuf;
    Ipp32u           dwFileSize;
    IJBITTREAMSTATE  stream;
    IJDECODESTATE    decodeState;
    IJXRESULT        rtCode;

    fseek(file, 0, SEEK_SET);
    memset(&decodeState, 0, sizeof(IJDECODESTATE));
    memset(&stream, 0, sizeof(IJBITTREAMSTATE));

    /* Calculate file length */
    fseek(file, 0, SEEK_END);
    dwFileSize=ftell(file);
    if (0==dwFileSize) {
        return FALSE;
    }
    fseek(file, 0, SEEK_SET);

    /* Init stream */

    /* Initialize to 0 */
    stream.nUsedBufBitsLen         = 0; 
    stream.nPrefetchedBits         = 0;
    stream.nNumValidPrefetchedBits = 0;
    stream.nMarker                 = 0;

    /* Estimate the compressed file size */
    stream.nMaxBufLen              = dwFileSize;
    stream.pBitStream              = (Ipp8u *)malloc(stream.nMaxBufLen);

    if (NULL==stream.pBitStream) {
        return FALSE;
    }

    /* Read stream data */
    dwFileSize=fread(stream.pBitStream, 1, stream.nMaxBufLen, file);
    if (dwFileSize!=(Ipp32u)(stream.nMaxBufLen)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }




#ifdef _GET_TIME_ON__
   //
   // Get the first time for performance calculation
   //
   gettimeofday(&tv3,&tz);
#endif


    /* Initialize Decompressor */
    rtCode=ijxDecompressInit (nDesiredColor,
                              IJX_OP_MULTIPLE,
                              &stream, &decodeState);
    if (!IJX_SUCCEEDED(rtCode)){
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    /* Get internal buffers' size used for decompressing */
    rtCode = ijxGetDecompBufLen (&nBufLen, &decodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    /* Init buffer for Decoding */
    pBuf=malloc(nBufLen);
    if (NULL==pBuf) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    rtCode = ijxDecompBufInit(pBuf, nBufLen, &decodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        free(pBuf);
        pBuf=NULL;
        return FALSE;
    }

    /* Init imageSpec */
    pDIBSpec->nWidth               = decodeState.imageSpec.nWidth;
    pDIBSpec->nHeight              = decodeState.imageSpec.nHeight;
    pDIBSpec->nPrecision           = decodeState.imageSpec.nPrecision;
    pDIBSpec->nNumComponent        = decodeState.imageSpec.nNumComponent;
    pDIBSpec->nClrMode             = decodeState.imageSpec.nColorMode;
    pDIBSpec->nBitsPerpixel        = decodeState.imageSpec.nBitsPerpixel;

    pDIBSpec->nStep                = IIP_WIDTHBYTES_4B((pDIBSpec->nWidth)*(pDIBSpec->nBitsPerpixel));
    pDIBSpec->nDataSize            = pDIBSpec->nStep*pDIBSpec->nHeight;

    if (IIP_CM_GRAY==pDIBSpec->nClrMode) {
        pDIBSpec->nNumComponent    = 1;
    } else if ((IIP_CM_BGR|IIP_CM_BGR555|IIP_CM_BGR565)&(pDIBSpec->nClrMode)) { 
        pDIBSpec->nNumComponent    = 3;
    } else if ((IIP_CM_BGRA)&(pDIBSpec->nClrMode)) { 
        pDIBSpec->nNumComponent    = 4;
    }

    /* Allocate memory for bitmap data */
	pDIBSpec->pBitmapData = (Ipp8u *) malloc(pDIBSpec->nDataSize);
    if (!pDIBSpec->pBitmapData) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;

        free(pBuf);
        pBuf=NULL;

		return FALSE;
	}



    /* Init ImageData */
    /* Bitmap in windows is store from bown to top with BGR format */
    nImageStep = -(pDIBSpec->nStep);
    pImageBuf  = &pDIBSpec->pBitmapData[pDIBSpec->nStep*(pDIBSpec->nHeight-1)]; 


    rtCode=ijxDecompress ((void **)&pImageBuf,
                          &nImageStep,  
                          &stream, 
                          &decodeState);

    free(stream.pBitStream);
    stream.pBitStream=NULL;

    free(pBuf);
    pBuf=NULL;

    return IJX_SUCCEEDED(rtCode)? TRUE : FALSE;
}


/* EOF */
